import React, {useEffect, useRef, useState} from 'react'
import {init, dispose, registerIndicator, Chart, registerOverlay} from 'klinecharts'
import Datasource from '../data/datasource'
import generatedDataList from '../generatedDataList'
import Layout from '../Layout'
import axios from 'axios'
import Style from './Style'
import KD from './indicators/KDJ'
import BOLLMA from "./indicators/BOLLMA";
import StrategiesCollection from "../strategies";
import moment from 'moment'
import _ from 'lodash'
import stocksData from '../data'
import tradingDates from '../data/dates'
import datasource from "../data/datasource";
import Overlays from "./overlays";
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
import {faMagnifyingGlass, faXmark} from "@fortawesome/free-solid-svg-icons";
import { io } from "socket.io-client";
const socket = io("wss://stock.deployment.cn", {
    reconnectionDelayMax: 10000
});

const Strategies = StrategiesCollection.strategies
const indicatorStrategies = Strategies.filter(strategy => strategy.indicator)
const Trader = StrategiesCollection.Trader
var trader;

const mainIndicators = ['MA', 'EMA', 'BOLL']
const subIndicators = ['KDJ', 'RSI', 'VOL']
let defaultFavs = [
    { code: "000001.SH", name: "上证指数" },
    // { code: "399001.SZ", name: "深证成指" },
    { code: "399006.SZ", name: "创业板指" },
    // { code: "000300.SH", name: "沪深300" },
    // { code: "000016.SH", name: "上证50" },
    // { code: "000905.SH", name: "中证500" }
]
let defaultStrategy = Strategies[0]
if(localStorage.getItem("strategy")) {
    // console.log("get default strategy", localStorage.getItem("strategy"))
    defaultStrategy = Strategies.find(strategy => strategy.name == localStorage.getItem("strategy"))
}
var dFavs = [...defaultFavs]
if(localStorage.getItem("favs")) {
    dFavs = JSON.parse(localStorage.getItem("favs"))
}
Overlays.forEach(overlay => {
    registerOverlay(overlay)
})
let lastLines = [];

export default function KLineChart () {
    const chart = useRef()
    const paneId = useRef('')
    const [stockName, setStockName] = useState("上证指数")
    const [code, setCode] = useState("000001.SH")
    const [prices, setPrices] = useState([])
    const [strategy, setStrategy] = useState(defaultStrategy)
    const [strategyStep, setStrategyStep] = useState(0)
    const [favs, setFavs] = useState(dFavs)
    const [period, setPeriod] = useState('1d')
    const [endTime, setEndTime] = useState(moment().format("YYYYMMDD150000"))
    const [searchedStocks, setSearchedStocks] = useState([])
    const [search, setSearch] = useState("")
    const [lines, setLines] = useState(300)
    const [price, setPrice] = useState(0)
    const [cash, setCash] = useState(0)
    const [position, setPosition] = useState(0)
    const [infoDisplay, setInfoDisplay] = useState(true)
    const [sourceReady, setSourceReady] = useState(false)
    const [strategyInfoShow, setStrategyInfoShow] = useState(true)
    const [menuShow, setMenuShow] = useState(false)
    const [selectedLine, setSelectedLine] = useState(null)

    useEffect(() => {
        if(trader) {
            trader.price = price;
        }
    }, [price, trader]);
    useEffect(() => {
        if(search){
            let stocks = []
            for(let stock of stocksData){
                if(stock.name.includes(search.toLowerCase()) || stock.code.includes(search.toLowerCase()) || stock.pinyin.includes(search.toLowerCase())){
                    stocks.push(stock)
                }
            }
            setSearchedStocks(stocks)
            // console.log(stocks)
        } else {
            setSearchedStocks([])
        }
    }, [search]);
    useEffect(() => {
        chart.current = init('indicator-k-line')
        window.klchart = chart.current
        registerIndicator(KD)
        registerIndicator(BOLLMA)
        paneId.current = chart.current.createIndicator('KD', false)
        chart.current.createIndicator('VOL', false)
        // chart.current.createIndicator('RSI', false)
        chart.current.setStyles(Style)
        chart.current.createIndicator("BOLLMA", false, { id: 'candle_pane' })
        chart.current.subscribeAction('onCandleBarClick', function (param) {
            // console.log(param)
        });
        trader = new Trader({setPrice, setCash, setPosition})
        datasource.init(function(res){
            if(res){
                console.log(res)
            }
            setSourceReady(true)
        })

        socket.on("lines", (lines) => {
            for(var line of lastLines){
                chart.current.removeOverlay(line)
            }
            console.log("lines", lines)
            for(var line of lines){
                (function(_line){
                    _line.onClick = function(){
                    console.log("click", _line);
                    setSelectedLine(_line);
                }})(line)
                chart.current.createOverlay(line)
            }
            lastLines = lines;
        })
        return () => {
            dispose('indicator-k-line')
        }
    }, [])
    useEffect(() => {
        if(code && chart.current && sourceReady){
            (async () => {
                for(var line of lastLines){
                    chart.current.removeOverlay(line)
                }
                const data = await Datasource.getKlines(code, period, endTime, lines)

                console.log(data)
                var last = data[data.length - 1];
                if(last){
                    data.push({
                        high: last.close,
                        low: last.close,
                        open: last.close,
                        close: last.close,
                        timestamp: last.timestamp + 1000 * 3600*24,
                        time: last.time + 1000 * 3600*24
                    })
                }


                chart.current.applyNewData(data)
                setPrices(data)
                for(let strategy of indicatorStrategies){
                    if(strategy.reset){
                        strategy.reset(chart.current)
                    }
                    strategy.update(chart.current, data)
                }
            })();
            console.log("going to join", code + ":" + period);
            socket.emit("join", code + ":" + period)

        }

    }, [code, chart, period, sourceReady]);
    useEffect(() => {
        setSearch('')
    }, [menuShow])
    const hideStrategyInfo = () => {
        setStrategyInfoShow(false)
    };
    const step = (previewCount) => {
        let step = strategyStep
        if (step >= prices.length) {
            return;
        }
        setStrategyStep(step + 1)
        console.log(step)
        if(step==0){
            chart.current.applyNewData([prices[0]])
        }else {
            chart.current.updateData(prices[step])
        }
        strategy.update(chart.current, prices.slice(0, step + 1))
    }
    const clear = () => {
        setStrategyStep(0)
        chart.current.applyNewData(prices)
    }

    const periods = ["1d", "1w"]
    return (
        <div style={{width: '100%', height: '100%'}} className={"container-fluid"}>
            <div className={"row"} style={{height: '100%'}}>
                <div style={{height: '100%', overflowY: 'scroll'}} className={"col-lg-2 col-xxl-2 d-lg-block d-xxl-block  " + (menuShow?"d-sm-block d-md-block d-block ": "d-none")}>
                    <div style={{display: 'flex', flexDirection: 'row', alignItems:'center'}}>
                        <input type="text" value={search} style={{flex:1}} placeholder={"标的代码/首字母"} onChange={(e) => {
                            setSearch(e.target.value)
                        }}/>
                        <FontAwesomeIcon icon={faXmark} onClick={()=>{
                            setSearch("")
                        }}/>
                    </div>
                    {searchedStocks.length > 0 && <div style={{marginTop: 10}}>
                        {searchedStocks.map((stock, index) => {
                                return <div key={index} style={{cursor: 'pointer', marginTop: 5}} onClick={() => {
                                    setCode(stock.code)
                                    setStockName(stock.name)
                                    setMenuShow(false)
                                }}>
                                    <div style={{color: code == stock.code ? "red" : "white"}}>{stock.name}</div>
                                    <div style={{fontSize: 12, color: 'rgba(255,255,255,0.5)'}}>{stock.code}</div>
                                </div>
                            }
                        )}
                    </div>}
                    <div style={{marginTop: 20}}>
                        <div>收藏</div>
                        <div style={{marginTop: 10}}>
                            {favs.map((fav, index) => {
                                return <div key={index} style={{cursor: 'pointer', marginTop: 5}} onClick={() => {
                                    setCode(fav.code)
                                    setStockName(fav.name)
                                    setMenuShow(false)
                                }}>
                                    <div style={{color: code == fav.code ? "red" : "white"}}>{fav.name}</div>
                                    <div style={{fontSize: 12, color: 'rgba(255,255,255,0.5)'}}>{fav.code}</div>
                                </div>
                            })}
                        </div>

                    </div>
                </div>
                <div className="k-line-chart-container col-lg-10 col-xxl-10 col-12" style={{paddingTop: 15}}>
                    {infoDisplay && <div className="k-line-chart-title">{stockName}</div>}
                    {infoDisplay && <div className={"periods"} style={{display: 'flex', flexDirection: 'row'}}>
                        {periods.map((p, index) => {
                            return <div key={index} className={period == p ? "active" : ""} onClick={() => {
                                setPeriod(p)
                            }}>{p}</div>
                        })}
                    </div>}
                    <div style={{display: 'flex', flexDirection: 'row', marginTop: 10, marginBottom:10, alignItems: 'center', fontSize:12}}
                         className={"col-lg-8 col-xxl-8 col-12"}>


                        <div style={{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
                            <div style={{cursor: 'pointer'}} onClick={() => {
                                chart.current.createOverlay({
                                    name: "straightLine",
                                    onDrawEnd: function (event) {
                                        var overlay = event.overlay;
                                        socket.emit("drawline", code, period, overlay);
                                    },
                                })
                            }}>画线
                            </div>
                            {selectedLine && <div style={{cursor: 'pointer', marginLeft: 15}} onClick={() => {
                                socket.emit("removeline", code, period, selectedLine.id)
                                chart.current.removeOverlay(selectedLine)
                                setSelectedLine(null)
                            }}>删除线
                            </div>}
                            {favs.filter(c => c.code == code).length == 0 &&
                                <div style={{cursor: 'pointer', marginLeft: 15}} onClick={() => {
                                    for (var fav of favs) {
                                        if (fav.code == code) {
                                            return;
                                        }
                                    }
                                    let newFavs = [...favs]
                                    newFavs.push({code, name: stockName})
                                    setFavs(newFavs)
                                    localStorage.setItem("favs", JSON.stringify(newFavs))
                                }}>收藏
                                </div>}


                            {favs.filter(c => c.code == code).length > 0 && defaultFavs.filter(c => c.code == code).length == 0 &&
                                <div style={{cursor: 'pointer', marginLeft: 15}} onClick={() => {
                                    let newFavs = [...favs]
                                    newFavs = newFavs.filter(c => c.code != code)
                                    setFavs(newFavs)
                                    localStorage.setItem("favs", JSON.stringify(newFavs))
                                }}>取消收藏</div>}
                            {trader &&
                                <div style={{
                                    color: 'white',
                                    marginLeft: 15
                                }}>模拟资产:{isNaN(Math.floor(cash + position)) ? 0 : Math.floor(cash + position)}</div>}
                        </div>
                    </div>
                    <div id="indicator-k-line" className="k-line-chart" style={{flex: 1}}/>
                    <div style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginBottom: 50, marginTop:30}}>
                        {strategyInfoShow&&<><div>策略</div>
                        <div style={{width: 50, marginLeft:15}}>
                            <select value={Strategies.findIndex(c => c.name == strategy.name)}
                                    onChange={e => {
                                        setStrategy(Strategies[e.target.value])
                                        localStorage.setItem("strategy", Strategies[e.target.value].name)
                                    }}>
                                {Strategies.filter(c => !c.indicator).map((s, index) => {
                                    return <option key={index} value={index}>{s.name}</option>
                                })}
                            </select>
                        </div></>}
                        {/*<div style={{marginLeft: 10}}>*/}
                        {/*    <div style={{marginBottom: 10}}>说明</div>*/}
                        {/*    <strategy.comment></strategy.comment>*/}
                        {/*</div>*/}

                        <div style={{marginLeft: 15, flex: 1}}>
                            {/*<div style={{marginBottom: 10}}>工具</div>*/}
                            <strategy.Tools getKlines={datasource.getKlines} indicatorStrategies={indicatorStrategies}
                                            setInfoDisplay={setInfoDisplay} code={code} chart={chart} trader={trader}
                                            setPrice={setPrice} prices={prices} stocks={stocksData}
                                            dates={tradingDates} hideStrategyInfo={hideStrategyInfo}></strategy.Tools>
                        </div>
                        <FontAwesomeIcon className={"d-xxl-none d-lg-none d-block"} icon={faMagnifyingGlass}  style={{color: 'white', marginLeft: 15, marginRight: 20}} onClick={()=>{
                            setMenuShow(true)
                        }}/>
                    </div>
                </div>
                {/*<div style={{padding: 15, display: 'flex', flexDirection: 'column'}}*/}
                {/*     className={"col-lg-2 col-xxl-2 col-12"}>*/}

                {/*    <div style={{display: 'flex'}}>*/}
                {/*        <button onClick={() => {*/}
                {/*            step(1)*/}
                {/*        }}>步进调试*/}
                {/*        </button>*/}

                {/*        <button style={{marginLeft: 5}} onClick={() => {*/}
                {/*            clear()*/}
                {/*        }}>清空*/}
                {/*        </button>*/}
                {/*        <button style={{marginLeft: 5}}>运行</button>*/}
                {/*    </div>*/}
                {/*</div>*/}
            </div>
        </div>

    )
}
